
// INCLUDES ********************************************************************

#include "TextElement.h"

#include "FTGL/ftgles.h"

#include "ftglesGlue.h"



// NAMESPACES ******************************************************************

namespace 
{
  const int gDefaultFontResolution = 72;
  
  const int gDefaultFontSize = 20;
}

using namespace Meteor;

#pragma mark -
#pragma mark Constructor
// -----------------------------------------------------------------------------

TextElement::TextElement()

: Drawable(), mFont( 0), mText(""), mFontSize( gDefaultFontSize), 
  mFontResolution( gDefaultFontResolution), mColor( 1.0, 1.0, 1.0, 1.0), 
  mAlignment( AlignmentLeft), mFontName( "")
{   
    mFont->FaceSize( mFontSize);
}

// -----------------------------------------------------------------------------

TextElement::TextElement( const std::string& fontname, const uint32_t zIndex,
                          const int fontSize)

: Drawable( zIndex), mFont( 0), mText( ""), mFontSize( fontSize),
  mFontResolution( gDefaultFontResolution), mFontName( fontname),
  mColor( 1.0, 1.0, 1.0, 1.0), mAlignment( AlignmentLeft)
{
    mFont = FontCache::Instance().AddObject( fontname);
    
    if ( mFont == 0)
    {
        // exception!?
        Logger::DebugLog("TextElement::TextElement", "Font is 0");
        
        return;
    }
    
    mFont->FaceSize( mFontSize);
}

// -----------------------------------------------------------------------------

TextElement::TextElement( const std::string& fontname, const int fontSize) : 
Drawable(), mFont( 0), mText( ""), mFontSize( fontSize), mFontResolution( gDefaultFontResolution), 
mColor( 1.0, 1.0, 1.0, 1.0), mAlignment( AlignmentLeft), mFontName( fontname)
{
    mFont = FontCache::Instance().AddObject( fontname);
    
    if ( mFont == 0)
    {
        //throw std::exception();
        Logger::DebugLog("TextElement::TextElement", "Font is 0");
        
        return;
    }
    
    mFont->FaceSize( mFontSize);
}


#pragma mark -
#pragma mark Destructor
// -----------------------------------------------------------------------------

TextElement::~TextElement()
{
    FontCache::Instance().RemoveObject( mFontName);
}


#pragma mark -
#pragma mark Font
// -----------------------------------------------------------------------------

void TextElement::SetFont( FTFont* const font)
{
    if ( font == 0)
    {
        return;
    }

    mFont = font;
    
    mFont->FaceSize( mFontSize, mFontResolution);
}

// -----------------------------------------------------------------------------

void TextElement::SetFont( std::string& fontname)
{
    mFont = FontCache::Instance().AddObject( fontname);
    
    mFont->FaceSize( mFontSize, mFontResolution);
}

// -----------------------------------------------------------------------------

const FTFont* TextElement::Font() const
{
    return mFont;
}


#pragma mark -
#pragma mark Fontsize
// -----------------------------------------------------------------------------

void TextElement::SetFontSize( const int fontSize)
{
    mFontSize = fontSize;
    
    mFont->FaceSize( mFontSize, mFontResolution);
}

// -----------------------------------------------------------------------------

const int TextElement::FontSize() const 
{
    return mFontSize;
}


#pragma mark -
#pragma mark Text
// -----------------------------------------------------------------------------

void TextElement::SetText( const std::string& text)
{
    mText = text;
}

// -----------------------------------------------------------------------------

const std::string& TextElement::Text() const
{
    return mText;
}

    
#pragma mark -
#pragma mark Color
// -----------------------------------------------------------------------------

void TextElement::SetColor( const float red, const float green, 
                            const float blue, const float alpha)
{
    mColor.SetRed( red);
    
    mColor.SetGreen( green);
    
    mColor.SetBlue( blue);
    
    mColor.SetAlpha( alpha);
}

// -----------------------------------------------------------------------------

void TextElement::SetColor( const struct Color& color)
{
    mColor = color;
}

// -----------------------------------------------------------------------------

const Color& TextElement::Color() const
{
    return mColor;
}


#pragma mark -
#pragma mark Alignment
// -----------------------------------------------------------------------------

void TextElement::SetAlignment( const TextAlignment alignment)
{
    mAlignment = alignment;
}

// -----------------------------------------------------------------------------

const TextAlignment TextElement::Alignment() const
{
    return mAlignment;
}



#pragma mark -
#pragma mark Update/draw cycles
// -----------------------------------------------------------------------------

void TextElement::Update( const float deltaTime)
{
}

// -----------------------------------------------------------------------------

void TextElement::Draw() const
{
    if ( !mFont || mVisible == false)
    {
        return;
    }
    
    glPushMatrix();
    
    glEnable( GL_BLEND);
    
	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    glEnableClientState( GL_VERTEX_ARRAY);
    
    glEnableClientState( GL_TEXTURE_COORD_ARRAY);
        
    Drawable::Draw();
    
    ftglInitImmediateModeGL();
    
    glColor4f( mColor.Red(), mColor.Green(), mColor.Blue(), mColor.Alpha());
    
    glClear( GL_CURRENT_COLOR);
    
    mFont->Render( mText.c_str());
    
    //! set implicitly by 'ftglInitImmediateModeGL'
    glDisableClientState( GL_COLOR_ARRAY);
    
    glDisableClientState( GL_TEXTURE_COORD_ARRAY);
    
    glDisableClientState( GL_VERTEX_ARRAY);
    
    glDisable( GL_BLEND);
    
    glPopMatrix();
}
